// Package dbservice
// @Author: zhangdi
// @File: chat_dialog
// @Version: 1.0.0
// @Date: 2023/7/3 15:39
package dbservice

import (
	"errors"
	"fmt"
	"ideatools/application/constant/enums"
	"ideatools/application/db/columns"
	"ideatools/application/db/dbdto"
	"ideatools/application/db/repository"
	"ideatools/application/db/sqllite"
	"ideatools/application/dto"
	"ideatools/application/pkgs/mylog"
	"ideatools/application/pkgs/utils"
	"ideatools/application/pkgs/where"
	"strings"
)

type DbChatDialogService struct {
	repo        *repository.ChatDialogRepository
	repoContent *repository.ChatContentRepository
}

func NewChatDialogService() *DbChatDialogService {
	return &DbChatDialogService{
		repo:        repository.NewChatDialogRepository(sqllite.GetDb()),
		repoContent: repository.NewChatContentRepository(sqllite.GetDb()),
	}
}

// CreateChatDialog 创建一个工具
func (s *DbChatDialogService) CreateChatDialog(toolId uint, clipTexts []string) dto.RespData {
	clipText := ""
	if clipTexts != nil {
		clipText = strings.Join(clipTexts, "[+]")
	}

	//
	dialogId, err := s.repo.Create(&dbdto.ChatDialogAdd{
		ToolId: toolId,
		Clips:  clipText,
	})

	if err != nil {
		return dto.RespError(err.Error())
	}

	//返回插入成功的id
	return dto.RespOk("创建完成", dialogId)
}

func (s *DbChatDialogService) GetContentInfoById(contentId uint) *dbdto.ChatContentInfo {

	info, err := s.repoContent.FindOneByWhere(where.Format(
		where.OptEqual(columns.ChatContentID, contentId),
	))
	if err != nil {
		return nil
	}
	dtoInfo := &dbdto.ChatContentInfo{}
	utils.DtoToEntity(info, dtoInfo)
	return dtoInfo
}

func (s *DbChatDialogService) GetToolChatDialogTotal(ToolId uint) int64 {
	wheres := where.Format()
	if ToolId > 0 {
		wheres = where.Format(where.OptEqual(columns.ChatDialogToolId, ToolId))
	}
	num, err := s.repo.GetTotalNum(wheres)
	if err != nil {
		return 0
	}

	return num
}

// ClearChatDialogContents 清空一个对话的所有内容
func (s *DbChatDialogService) ClearChatDialogContents(ChatDialogId uint) dto.RespData {

	//

	err := s.repoContent.DeleteByFieldValue(
		where.Format(where.OptEqual(columns.ChatContentChatDialogId, ChatDialogId)))

	if err != nil {
		return dto.RespError(err.Error())
	}

	//返回插入成功的id
	return dto.RespOk("清空完成", nil)
}

func (s *DbChatDialogService) UpdateAiRespond(contentId uint, data *dbdto.ChatContentUpdate) error {
	wheres := where.Format(where.Opt(columns.ChatContentID, "=", contentId))
	//data := &dbdto.ChatContentUpdate{
	//	Content:   content,
	//	IsHanding: isHanding,
	//	IsError:   isError,
	//	ErrorMsg:  errorMsg,
	//}
	err := s.repoContent.Update(wheres, data)
	return err
}

// AddChatContent 像一个对话中插入一条记录
func (s *DbChatDialogService) AddChatContent(chatDialogId uint, content, role string) (*dbdto.ChatContentInfo, error) {

	dialogInfo, err := s.repo.FindOneByWhere(where.Format(where.OptEqual(columns.ChatDialogID, chatDialogId)))
	if dialogInfo == nil {
		return nil, errors.New("对话不存在 dialogInfo==nil")
	}

	//创建details的
	isHanding := false
	if role == enums.GptRoleAI {
		//如果是AI则消息状态默认处理中
		isHanding = true
	}
	dtoData := &dbdto.ChatContentAdd{
		Role:         role,
		Content:      content,
		IsHanding:    isHanding,
		ToolId:       dialogInfo.ToolId,
		ChatDialogId: chatDialogId,
	}
	entityInfo, err := s.repoContent.Create(dtoData)

	if err != nil {
		return nil, err
	}

	dtoInfo := &dbdto.ChatContentInfo{}
	utils.DtoToEntity(entityInfo, dtoInfo)
	//插入
	return dtoInfo, nil
}

// GetListChatContent 根据对话id查询消息列表
func (s *DbChatDialogService) GetListChatContent(chatDialogId uint, isDesc bool) dto.RespData {
	wheres := where.Format(where.OptEqual(columns.ChatContentChatDialogId, chatDialogId))
	extra := &where.Extra{
		OrderByColumn: columns.ChatContentID,
		OrderByDesc:   isDesc,
		Limit:         1000,
	}
	List, err := s.repoContent.FindListExtra(wheres, extra)
	if err != nil {
		return dto.RespError(err.Error())
	}
	return dto.RespOk("ok", List)
}

func (s *DbChatDialogService) GetDialogInfo(dialogId uint) *dbdto.ChatDialogInfo {
	info, err := s.repo.FindOneByWhere(where.Format(where.OptEqual(columns.ChatDialogID, dialogId)))
	if err != nil {
		mylog.Error("GetDialogInfo()" + err.Error())
		return nil
	}
	dtoInfo := &dbdto.ChatDialogInfo{}
	utils.DtoToEntity(info, dtoInfo)
	return dtoInfo
}

// GetLeastDialogInfo 获取最新的对话
func (s *DbChatDialogService) GetLeastDialogInfo() *dbdto.ChatDialogInfo {
	list, err := s.repo.FindListExtra(where.Format(), &where.Extra{
		OrderByColumn: columns.ChatDialogID,
		OrderByDesc:   true,
		Limit:         1,
	})
	if err != nil {
		mylog.Error("GetDialogInfo()" + err.Error())
		return nil
	}
	if list == nil || len(list) <= 0 {
		mylog.Error("GetDialogInfo() list==nil")
		return nil
	}

	info := list[0]
	dtoInfo := &dbdto.ChatDialogInfo{}
	utils.DtoToEntity(info, dtoInfo)
	return dtoInfo
}

func (s *DbChatDialogService) GetListChatDialog(ToolId int, page, pageSize int) *dbdto.ChatDialogSelect {
	wheres := where.Format()
	if ToolId > 0 {
		wheres = where.Format(where.OptEqual(columns.ChatDialogToolId, ToolId))
	}
	extra := &where.Extra{
		OrderByColumn: columns.ChatDialogID,
		OrderByDesc:   true,
		Limit:         pageSize,
		Offset:        (page - 1) * pageSize,
	}

	List, err := s.repo.FindListExtra(wheres, extra)
	if err != nil {
		mylog.Error(err.Error())
		return nil
	}
	var resList []*dbdto.ChatDialogInfo
	for _, dialog := range List {
		dtoInfo := &dbdto.ChatDialogInfo{}
		utils.DtoToEntity(dialog, dtoInfo)
		if dtoInfo.ToolId > 0 {
			ToolInfo := NewUserToolService().FindOneById(dtoInfo.ToolId)

			dtoInfo.ToolIcon = ToolInfo.ToolIcon
			dtoInfo.FirstContent = s.GetDialogFirstContent(dialog.ID)
			dtoInfo.ToolName = ToolInfo.ToolName
			dtoInfo.ToolIconColor = ToolInfo.ToolIconColor
		}
		resList = append(resList, dtoInfo)
	}

	total, err := s.repo.GetTotalNum(wheres)
	result := &dbdto.ChatDialogSelect{
		List:     resList,
		Total:    total,
		CurrPage: 0,
		PageSize: 0,
	}
	return result
}

func (s *DbChatDialogService) GetDialogFirstContent(dialogId uint) string {
	wheres := where.Format(where.Opt(columns.ChatContentChatDialogId, "=", dialogId))
	extras := &where.Extra{
		OrderByColumn: columns.ChatContentID,
		OrderByDesc:   false,
		Limit:         1,
	}
	list, err := s.repoContent.FindListExtra(wheres, extras)
	if err != nil {
		mylog.Error(fmt.Sprintf("GetDialogFirstContent-%v", dialogId))
		return ""
	}
	if list != nil && len(list) > 0 {
		return list[0].Content
	}
	return ""
}

// DelChatDialog 删除一个对话
func (s *DbChatDialogService) DelChatDialog(id int) dto.RespData {
	wheres := where.Format(where.Opt(columns.ChatDialogID, "=", id))
	err := s.repo.DeleteByFieldValue(wheres)
	if err != nil {
		return dto.RespError(err.Error())
	}
	//同步删除消息记录
	wheresContent := where.Format(where.OptEqual(columns.ChatContentChatDialogId, id))
	err = s.repoContent.DeleteByFieldValue(wheresContent)
	if err != nil {
		return dto.RespError("同步删除消息记录error:" + err.Error())
	}

	//删除完成
	return dto.RespOk("ok", nil)

}

// DelChatContent 删除一条消息
func (s *DbChatDialogService) DelChatContent(contentId int) dto.RespData {
	wheres := where.Format(where.Opt(columns.ChatContentID, "=", contentId))
	info, _ := s.repoContent.FindOneByWhere(wheres)
	if info == nil {
		return dto.RespError("记录{" + fmt.Sprintf("%v", contentId) + "}不存在，无法删除")
	}
	err := s.repoContent.DeleteByFieldValue(wheres)
	if err != nil {
		return dto.RespError(err.Error())
	}

	//删除完成
	return dto.RespOk("ok", nil)

}

func (s *DbChatDialogService) Gen1() *dbdto.ClipboardInfo {

	return &dbdto.ClipboardInfo{}

}
